package com.zeyu.framework.monitors.webserver.web;

import com.google.common.collect.Lists;
import com.zeyu.framework.core.persistence.Page;
import com.zeyu.framework.core.web.BaseController;
import com.zeyu.framework.core.web.Result;
import com.zeyu.framework.modules.sys.utils.UserUtils;
import com.zeyu.framework.monitors.webserver.WebServerCollector;
import com.zeyu.framework.monitors.webserver.entity.MemoryUsageStatus;
import com.zeyu.framework.monitors.webserver.entity.RequestProcessorStatus;
import com.zeyu.framework.monitors.webserver.entity.WebServerStatus;
import com.zeyu.framework.monitors.webserver.service.WebServerService;
import com.zeyu.framework.tools.report.charts.ChartData;
import com.zeyu.framework.tools.report.dynamic.ReportUtils;
import com.zeyu.framework.utils.Collections3;
import com.zeyu.framework.utils.DateUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletRequest;
import java.util.List;

/**
 * web server 监控和操作controller
 * Created by zeyuphoenix on 16/8/27.
 */
@Controller
@RequestMapping(value = "/monitors/web")
public class WebServerController extends BaseController {

    // ================================================================
    // Constants
    // ================================================================

    // ================================================================
    // Fields
    // ================================================================

    @Autowired
    private WebServerCollector webServerCollector;

    @Autowired
    private WebServerService webServerService;

    // ================================================================
    // Constructors
    // ================================================================

    // ================================================================
    // Methods from/for super Interfaces or SuperClass
    // ================================================================

    // ================================================================
    // Public or Protected Methods
    // ================================================================

    /**
     * 页面
     */
    @RequestMapping(value = {"index", ""})
    public String index() {

        return "modules/monitors/webServer";
    }

    /**
     * 获取最后一次监控的基本信息,这些信息不保存数据库
     */
    @ResponseBody
    @RequestMapping("current")
    public WebServerStatus currentSatatus() {
        WebServerStatus webServerStatus = webServerCollector.getWebServerStatus();
        if (webServerStatus == null) {
            // 未扫描过则扫描一次
            webServerStatus = webServerCollector.getCurrentWebServerStatus();
        }
        webServerStatus.setContextPath(DateUtils.formatDateTimeLocal(webServerStatus.getUptime()));
        return webServerStatus;
    }


    /**
     * 获取web server内存使用列表
     */
    @RequestMapping(value = "memList")
    @ResponseBody
    public Page<MemoryUsageStatus> memList(HttpServletRequest request) {
        Page<MemoryUsageStatus> page = new Page<>(request);
        page.setCount(1);
        page.setList(webServerCollector.getMemoryUsageStatusList());
        return page;
    }

    /**
     * 获取web server 请求信息列表
     */
    @RequestMapping(value = "reqList")
    @ResponseBody
    public Page<RequestProcessorStatus> reqList(HttpServletRequest request) {
        Page<RequestProcessorStatus> page = new Page<>(request);
        page.setCount(1);
        page.setList(webServerCollector.getRequestProcessorStatusList());
        return page;
    }

    /**
     * web server的监控图表
     * 监控断掉的问题没办法
     */
    @RequestMapping(value = "chartData")
    @ResponseBody
    public ChartData chartData(int type) {

        ChartData chartData = new ChartData();

        // 默认查询是5分钟一次,则1小时12个,一天288个,一个月9000以内,使用带浮动条的全部查看
        List<WebServerStatus> webServerStatusList = webServerService.findList(new WebServerStatus());
        if (!Collections3.isEmpty(webServerStatusList)) {
            // 角度
            List<String> xAxis = Lists.newArrayList();
            // 指标
            List<List<Number>> series = Lists.newArrayList();

            // type --> 1:内存  2:线程数  3:请求数  4:网络字节数  5:执行时间

            // 转换数据
            for (WebServerStatus webServerStatus : webServerStatusList) {
                xAxis.add(DateUtils.formatDate(webServerStatus.getTime(), "dd日HH:mm"));
                if (type == 1) {
                    // 内存
                    ReportUtils.addSerie(series, 3);
                    // '最大的内存大小(m)',
                    series.get(0).add(webServerStatus.getMaxMemory());
                    // '可用的内存大小(m)',
                    series.get(1).add(webServerStatus.getFreeMemory());
                    // '总共的物理内存(m)',
                    series.get(2).add(webServerStatus.getTotalMemory());

                } else if (type == 2) {
                    // 连接
                    ReportUtils.addSerie(series, 5);
                    // 启动线程数
                    series.get(0).add(webServerStatus.getTotalStartedThreadCount());
                    // 最大线程数
                    series.get(1).add(webServerStatus.getMaxThreads());
                    // 当前线程总数
                    series.get(2).add(webServerStatus.getCurrentThreadCount());
                    // 繁忙线程数
                    series.get(3).add(webServerStatus.getCurrentThreadsBusy());
                    // 保存连接线程数
                    series.get(4).add(webServerStatus.getKeepAliveCount());

                } else if (type == 3) {
                    // 请求数
                    ReportUtils.addSerie(series, 2);
                    // 总请求数
                    series.get(0).add(webServerStatus.getRequestCount());
                    // 错误请求数
                    series.get(1).add(webServerStatus.getErrorCount());

                } else if (type == 4) {
                    // 字节数
                    ReportUtils.addSerie(series, 2);
                    // 接收字节数
                    series.get(0).add(webServerStatus.getBytesReceived());
                    // 发送字节数
                    series.get(1).add(webServerStatus.getBytesSent());

                } else if (type == 5) {
                    // 执行时间
                    ReportUtils.addSerie(series, 2);
                    // 最大执行时间
                    series.get(0).add(webServerStatus.getMaxTime());
                    // 执行时间
                    series.get(1).add(webServerStatus.getProcessingTime());

                }
            }

            chartData.setxAxis(xAxis);
            chartData.setSeries(series);
        }

        return chartData;
    }


    /**
     * web server重新启动
     */
    @RequestMapping(value = "restart")
    @ResponseBody
    public Result restart() {
        Result result = new Result();
        if (MODE_DEMO) {
            result.setStatus(Result.ERROR);
            result.setMessage("演示模式，不允许操作!");
            return result;
        }
        if (!UserUtils.getUser().isAdmin()) {
            result.setStatus(Result.ERROR);
            result.setMessage("只能使用管理员用户才可以操作!");
            return result;
        }
        // TODO
        result.setStatus(Result.SUCCESS);
        result.setMessage("Web Server(tomcat)重新启动成功");
        return result;
    }

    // ================================================================
    // Getter & Setter
    // ================================================================

    // ================================================================
    // Private Methods
    // ================================================================

    // ================================================================
    // Inner or Anonymous Class
    // ================================================================

    // ================================================================
    // Test Methods
    // ================================================================

}
